package com.greyu.ysj.authorization.interceptor;

import com.greyu.ysj.authorization.annotation.Authorization;
import com.greyu.ysj.authorization.annotation.DuplicateSubmitToken;
import com.greyu.ysj.authorization.manager.TokenManager;
import com.greyu.ysj.authorization.model.TokenModel;
import com.greyu.ysj.config.Constants;
import com.greyu.ysj.entity.TableBlackList;
import com.greyu.ysj.service.TableBlackListServer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Hashtable;

/**
 * @Description: 自定义拦截器，判断此请求是否有权限
 * @see com.greyu.ysj.authorization.annotation.Authorization
 * @Author: gre_yu@163.com
 * @Date: Created in 8:48 2018/2/1
 */
@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private TokenManager manager;
    @Autowired
    private TableBlackListServer tableBlackListServer;
    
    private volatile Hashtable<String, Integer> statusMap = new Hashtable<>();
    
    private boolean urlForbiddenFilter(String url) {
    	System.out.println("urlForbiddenFilter===>" + url);
    	System.out.println("[1]===>" + url.split("/")[1]);
		if (!( url.split("/")[1].equals("cbt")
				|| url.split("/")[1].equals("akb_miner_server"))
			)
			
		{
			return true;
		}
		if (!( url.split("/")[2].equals("tableLevelAsset") 
				||url.split("/")[2].equals("cbt")
				|| url.split("/")[2].equals("img")
				|| url.split("/")[2].equals("app") 
				|| url.split("/")[2].equals("error")
				|| url.split("/")[2].equals("income")
				|| url.split("/")[2].equals("invitation")
				|| url.split("/")[2].equals("")) //兼容新版本
			) {
			return true;
		}
		return false;
	}
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println(request.getRequestURI());
        
        
        
        
        
//        如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
//      从header中得到token
        String authorization = request.getHeader(Constants.AUTHORIZATION);
        
        
        if (method.isAnnotationPresent(DuplicateSubmitToken.class)) {
        	String userId = request.getParameter("userId");
        	 if (userId!=null) {
             	Integer status = statusMap.get(request.getRequestURI()+userId);
             	if (status!=null && status==1) {
                	response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
     				return false;
     			}else{
     				statusMap.put(request.getRequestURI()+userId, 1);
     			}
     		}
        
        }
        
     
        String language=request.getHeader(Constants.LANGUAGE);
        System.out.println("authorization ="+authorization);
        System.out.println("language ="+language);
//        验证token
        TokenModel model = this.manager.getToken(authorization);
        System.out.println("model ="+model);
        
        String url = request.getRequestURI();
        System.out.println(url);
        String ipRemoteAddress = request.getRemoteAddr();
        //进行判断是否存在到黑名单中
        if (true == this.tableBlackListServer.isAddressIsExit(ipRemoteAddress)) {
        	System.out.println(ipRemoteAddress+" is in black list,forbidden~!");
        	System.out.println("isAddressIsExit error 401 SC_FORBIDDEN");
        	response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }
        
        //进行过滤非法的url
        if (urlForbiddenFilter(url)) {
        	System.out.println(ipRemoteAddress+" is in black list,forbidden~!");
        	TableBlackList tableBlackList = new TableBlackList();
        	tableBlackList.setAddress(ipRemoteAddress);
        	this.tableBlackListServer.save(tableBlackList);
        	System.out.println("curlForbiddenFilter error 401 SC_FORBIDDEN");
        	response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }
        
        if (method.getAnnotation(Authorization.class) != null) {
			if (null == model) {
				System.out.println("getAnnotation is null return false");
				response.setStatus(HttpServletResponse.SC_FORBIDDEN);
				return false;
			} else {
				System.out.println(" test =====>>>>>this.manager.checkToken(model)");
				if (this.manager.checkToken(model)) {
					//如果token验证成功，将token对应的userId存在request中，便于之后注入
					System.out.println("checkToken ok,return ;;;;;");
					request.setAttribute(Constants.CURRENT_USER_ID, model.getUserId());
					System.out.println(model.toString());
					// response.setHeader(Constants.AUTHORIZATION, model.getToken());
					return true;
				}else
				{
					System.out.println("checkToken error,return 403 SC_FORBIDDEN");
					response.setStatus(HttpServletResponse.SC_FORBIDDEN);
					return false;
				}
			}
		}
        return true;
    }
    
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //执行中
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //执行之后
    	 HandlerMethod handlerMethod = (HandlerMethod) handler;
         Method method = handlerMethod.getMethod();
    	 
    	 if (method.isAnnotationPresent(DuplicateSubmitToken.class)) {
    		 String userId = request.getParameter("userId");
    		 if (userId != null) {
    	            statusMap.put(request.getRequestURI()+userId, 2);
    	        }
    	 }
       
    }
}
